package fuzion24.device.vulnerability.test.job;

import android.app.DownloadManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.evernote.android.job.Job;
import com.nowsecure.android.vts.BuildConfig;
import com.nowsecure.android.vts.R;

import fuzion24.device.vulnerability.test.AndroidVTSApplication;
import fuzion24.device.vulnerability.test.ui.MainActivity;
import fuzion24.device.vulnerability.update.client.RetrofitClient;
import fuzion24.device.vulnerability.update.model.GithubRelease;
import fuzion24.device.vulnerability.update.service.GithubApiService;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Job to run the tests.
 */
public class CheckForUpdatesJob extends Job {

    public static final String TAG = "job_check_for_updates_tag";

    @Override
    @NonNull
    protected Result onRunJob(Params params) {
        checkForUpdates(getContext(), null);

        return Result.SUCCESS;
    }

    public static void checkForUpdates(final Context context, final MaterialDialog progressDialog) {
        GithubApiService service = RetrofitClient.getRetrofitClient().create(GithubApiService.class);

        service.getLatestRelease().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .unsubscribeOn(Schedulers.io())
            .subscribe(new Subscriber<GithubRelease>() {

                @Override
                public void onCompleted() {
                    if (progressDialog == null) {
                        return;
                    }

                    progressDialog.dismiss();
                }

                @Override
                public void onError(Throwable e) {
                    Toast.makeText(context, R.string.update_error, Toast.LENGTH_LONG).show();
                }

                @Override
                public void onNext(final GithubRelease githubRelease) {
                    Double currentVersion = Double.parseDouble(BuildConfig.VERSION_NAME.replace("v.", ""));
                    Double repositoryVersion = Double.parseDouble(githubRelease.getTag_name().replace("v.", ""));

                    // Check if a new version is available.
                    if (repositoryVersion > currentVersion) {
                        if (progressDialog == null) {
                            NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_notification).setContentTitle(context.getString(R.string.app_name))
                                .setStyle(new NotificationCompat.BigTextStyle().bigText(context.getString(R.string.update_available)))
                                .setAutoCancel(true)
                                .setContentText(context.getString(R.string.update_available));
                            Intent resultIntent = new Intent(context, MainActivity.class);
                            PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

                            builder.setContentIntent(resultPendingIntent);

                            NotificationManager notifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

                            notifyMgr.notify(1000, builder.build());

                            return;
                        }

                        new MaterialDialog.Builder(context)
                            .title(R.string.update_available_title)
                            .content(context.getString(R.string.update_avaiable_description, githubRelease.getTag_name()))
                            .positiveText(R.string.update)
                            .negativeText(R.string.dismiss)
                            .onPositive(new MaterialDialog.SingleButtonCallback() {
                                @Override
                                public void onClick(@NonNull MaterialDialog materialDialog, @NonNull DialogAction dialogAction) {
                                    ((AndroidVTSApplication) context.getApplicationContext()).downloadFilename = String.format("AndroidVTS-%s.apk", githubRelease.getTag_name());
                                    ((AndroidVTSApplication) context.getApplicationContext()).downloadManager.enqueue(new DownloadManager.Request(Uri.parse(githubRelease.getAssets().get(0).getBrowser_download_url()))
                                        .setTitle("Android VTS")
                                        .setDescription(context.getString(R.string.downloading_update))
                                        .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, ((AndroidVTSApplication) context.getApplicationContext()).downloadFilename));
                                }
                            })
                            .show();

                        return;
                    }

                    // Only show the toast if it was the user who requested the update check.
                    if (progressDialog != null) {
                        Toast.makeText(context, R.string.no_update_available, Toast.LENGTH_LONG).show();
                    }
                }

            });
    }
}